package com.shiguiwu.springmybatis.spring.transaction;

import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.sql.DataSource;

/**
 * @description: 事务管理综合案例
 * @author: stone
 * @date: Created by 2022/1/8 20:38
 * @version: 1.0.0
 * @pakeage: com.shiguiwu.springmybatis.spring.transaction
 */
public class TransactionPlusTests {


    public static void main(String[] args) {

        DataSourceBuilder<?> dataSourceBuilder = DataSourceBuilder.create();
        dataSourceBuilder.driverClassName("com.mysql.cj.jdbc.Driver");
        dataSourceBuilder.url("jdbc:mysql://127.0.0.1:3306/lunwen?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai");
        dataSourceBuilder.username("root");
        dataSourceBuilder.password("123456");


        DataSource dataSource = dataSourceBuilder.build();

        boolean a = true;

        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        //1.定义一个事务管理器
        PlatformTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);

        //清空数据
        jdbcTemplate.update("truncate table book");

        System.out.println("PROPAGATION_REQUIRED start ==========================================================");

        //2.定义一个事务属性
        TransactionDefinition transactionDefinition = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED);

        //3.取一个事务状态,开启事务了
        TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);

        //设置扩展点
        addSynchronization("ts-1", 2);
        addSynchronization("ts-2", 1);
        try {
            //4.执行业务
            jdbcTemplate.update("insert into book(book_name) values (?)", "书屋");

            if (a) {
                throw new RuntimeException("===");
            }
            jdbcTemplate.update("insert into book(book_name) values (?)", "成是非");

            //此时，在执行一个方法事务
            other(jdbcTemplate, transactionManager);

            //5.提交事务
            System.out.println("PROPAGATION_REQUIRED 准备commit");
            transactionManager.commit(transactionStatus);
            System.out.println("PROPAGATION_REQUIRED commit完毕");
        } catch (Exception e) {
            e.printStackTrace();
            //6.回滚事务：platformTransactionManager.rollback
            transactionManager.rollback(transactionStatus);

        }

        System.out.println("after==========================>:" + jdbcTemplate.queryForList("SELECT * from book"));
    }

    private static void other(JdbcTemplate jdbcTemplate, PlatformTransactionManager transactionManager) {
        System.out.println("PROPAGATION_REQUIRES_NEW start");
        TransactionDefinition transactionDefinition = new
                DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
        jdbcTemplate.update("insert into book (book_name) values (?)", "test2-1");
        jdbcTemplate.update("insert into book (book_name) values (?)", "test2-2");
        addSynchronization("ts-3", 2);
        addSynchronization("ts-4", 1);
        System.out.println("PROPAGATION_REQUIRES_NEW 准备commit");
        transactionManager.commit(transactionStatus);
        System.out.println("PROPAGATION_REQUIRES_NEW commit完毕");
    }






    private static void addSynchronization(final String name, final int order) {
        if (TransactionSynchronizationManager.isActualTransactionActive()) {
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
                @Override
                public int getOrder() {
                    return order;
                }

                @Override
                public void suspend() {
                    System.out.println(name + ":suspend");
                }

                @Override
                public void resume() {
                    System.out.println(name + ":resume");
                }

                @Override
                public void flush() {
                    System.out.println(name + ":flush");
                }

                @Override
                public void beforeCommit(boolean readOnly) {
                    System.out.println(name + ":beforeCommit ==>" + readOnly);
                }

                @Override
                public void beforeCompletion() {
                    System.out.println(name + ":beforeCompletion");
                }

                @Override
                public void afterCommit() {
                    System.out.println(name + ":afterCommit");
                }

                @Override
                public void afterCompletion(int status) {
                    System.out.println(name + ":afterCompletion ==> " + status);
                }
            });
        }
    }


}


/*
 * Copyright 2002-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

